#!/usr/bin/perl

use strict;
use PGPLOT;
use Time::Local;

# this script takes a miriad uv dataset and makes a plot
# summarising the sources in it, their times and configurations

# the arguments
# --dataset set.uv : the dataset to investigate
# --cycletime n : the cycletime of the dataset in seconds
# --output pgplot_device : the PGPLOT device to use
my $dataset;
my $cycletime=10; # default cycletime of 10 seconds
my $pgplot_device="8/xs"; # default to using /xs
for (my $i=0;$i<=$#ARGV;$i++){
    if ($ARGV[$i] eq "--dataset"){
	$i++;
	$dataset=$ARGV[$i];
    } elsif ($ARGV[$i] eq "--cycletime"){
	$i++;
	$cycletime=$ARGV[$i];
    } elsif ($ARGV[$i] eq "--output"){
	$i++;
	$pgplot_device=$ARGV[$i];
	print "will use PGPLOT device $pgplot_device\n";
    }
}

if ($dataset eq ""){
    die "no dataset specified\n";
}

# generate the uvindex log
my $interval=$cycletime/60.0;
my $uvindex_command="uvindex vis=".$dataset." interval=".$interval." log=uvindex.log";
system $uvindex_command;

# read the uvindex log
open(UVINDEX,"uvindex.log");
my @date_time;
my @source;
my @calcode;
my @nants;
my @channels;
my @freqconfig;
while(<UVINDEX>){
    chomp;
    my $line=$_;
    if ($line=~/^\d{2}\D{3}\d{2}\:\d{2}\:\d{2}\:\d{2}\.\d/){
	# what we want
	my @els=split(/\s+/,$line);
	push @date_time,$els[0];
	push @source,$els[1];
	push @calcode,$els[2];
	push @nants,$els[3];
	push @channels,$els[4];
	push @freqconfig,$els[6];
    }
}
close(UVINDEX);

# start the plot
pgopen($pgplot_device);

# find the first and last times
my $first_time=&parse_miriad_time($date_time[0]);
my $last_time=&parse_miriad_time($date_time[0]);
for (my $i=1;$i<=$#date_time;$i++){
    my $current_time=&parse_miriad_time($date_time[$i]);
    if ($current_time<$first_time){
	$first_time=$current_time;
    }
    if ($current_time>$last_time){
	$last_time=$current_time;
    }
}

# find how many configs there are
my $current_source=$source[0];
my $current_calcode=$calcode[0];
my $current_nants=$nants[0];
my $current_channels=$channels[0];
my $current_freqconfig=$freqconfig[0];
my $nconfigs=1;
my @tconfigs;
for (my $i=1;$i<=$#date_time;$i++){
    if (($source[$i] ne $current_source)||
	($calcode[$i] ne $current_calcode)||
	($nants[$i] != $current_nants)||
	($channels[$i] != $current_channels)||
	($freqconfig[$i] != $current_freqconfig)){
	my $configstring="$current_source/$current_calcode/$current_nants/$current_channels/$current_freqconfig";
	my $isnew=1;
	for (my $j=0;$j<=$#tconfigs;$j++){
	    if ($tconfigs[$j] eq $configstring){
		$isnew=0;
	    }
	}
	if ($isnew==1){
	    push @tconfigs,$configstring;
	    $nconfigs++;
	}
	$current_source=$source[$i];
	$current_calcode=$calcode[$i];
	$current_nants=$nants[$i];
	$current_channels=$channels[$i];
	$current_freqconfig=$freqconfig[$i];
    }
}
my $min_y_value=0;
my $max_y_value=100;
my $y_interval=($max_y_value-$min_y_value)/$nconfigs;

# now set up the axes
pgswin($first_time,$last_time,$min_y_value,$max_y_value);
pgtbox('BCNTSZ',0,0,'BC',0,0);
pgsah(2,70.0,1.0);
pglab("Time","Configuration (source/calcode/nants/nchans/freqconfig)","Observation summary for ".$dataset);

# now make the plot
my $start_time=$first_time;
my $start_time_string=$date_time[0];
my $end_time=$first_time;
my $end_time_string=$date_time[0];
$current_source=$source[0];
$current_calcode=$calcode[0];
$current_nants=$nants[0];
$current_channels=$channels[0];
$current_freqconfig=$freqconfig[0];
my $current_y=$max_y_value-$y_interval;
my @configs;
my @config_ys;
my @config_earlytime;
my @config_latetime;
for (my $i=1;$i<=$#date_time;$i++){
    # first find the time this source/config ends
    if (($source[$i] ne $current_source)||
	($calcode[$i] ne $current_calcode)||
	($nants[$i] != $current_nants)||
	($channels[$i] != $current_channels)||
	($freqconfig[$i] != $current_freqconfig)){
	# something has changed
	$end_time=&parse_miriad_time($date_time[$i-1]);
	$end_time_string=$date_time[$i-1];
	# make the config string
	my $configstring="$current_source/$current_calcode/$current_nants/$current_channels/$current_freqconfig";
	print "$configstring: $start_time_string -> $end_time_string\n";
	# where to put it
	my $yheight=$current_y;
	my $found_config=0;
	for (my $j=0;$j<=$#configs;$j++){
	    if ($configs[$j] eq $configstring){
		$found_config=1;
		$yheight=$config_ys[$j];
		if ($start_time<$config_earlytime[$j]){
		    $config_earlytime[$j]=$start_time;
		}
		if ($end_time>$config_latetime[$j]){
		    $config_latetime[$j]=$end_time;
		}
	    }
	}
	if ($found_config==0){
	    push @configs,$configstring;
	    push @config_ys,$current_y;
	    push @config_earlytime,$start_time;
	    push @config_latetime,$end_time;
	    $current_y-=$y_interval;
	}
	# make a double ended arrow
	pgsch(0.2);
	pgarro($start_time,$yheight,$end_time,$yheight);
	pgarro($end_time,$yheight,$start_time,$yheight);
	# continue with the new config
	$start_time=&parse_miriad_time($date_time[$i]);
	$start_time_string=$date_time[$i];
	$current_source=$source[$i];
	$current_calcode=$calcode[$i];
	$current_nants=$nants[$i];
	$current_channels=$channels[$i];
	$current_freqconfig=$freqconfig[$i];
    }
}

for (my $j=0;$j<=$#configs;$j++){
    pgsch(0.6);
    my ($configxlength,$configylength);
    pglen(4,$configs[$j],$configxlength,$configylength);
    my $startdiff=$config_earlytime[$j]-$first_time;
    my $enddiff=$last_time-$config_latetime[$j];
    my $leftxpos;
    if ($startdiff>$enddiff){
	$leftxpos=$config_earlytime[$j]-$configxlength-120;
    } else {
	$leftxpos=$config_latetime[$j]+120;
    }
    pgtext($leftxpos,$config_ys[$j],$configs[$j]);
}

pgclos();

sub parse_miriad_time {
    my $timestring=$_[0];
    $timestring=~m/(\d{2})(\D{3})(\d{2})\:(\d{2})\:(\d{2})\:(\d{2}\.\d)/;
    my $bdt_year=$1+100;
    my $bdt_month=&month_parse($2);
    my $bdt_date=$3;
    my $bdt_hour=$4;
    my $bdt_minute=$5;
    my $bdt_second=$6;
    my $simpletime=timegm($bdt_second,$bdt_minute,$bdt_hour,$bdt_date,$bdt_month,$bdt_year);
    # get the day of year
    my ($s,$m,$h,$md,$mo,$y,$w,$yd,$id)=gmtime($simpletime);
    # get the number of seconds since the start of the day
    while ($simpletime>86400){
	$simpletime-=86400;
    }
    # and add the day of year
    $simpletime+=$yd*86400;

    return $simpletime;
}

sub month_parse {
    my $month_string=$_[0];
    my $month_number;
    if ($month_string eq "JAN"){
	$month_number=0;
    } elsif ($month_string eq "FEB"){
	$month_number=1;
    } elsif ($month_string eq "MAR"){
	$month_number=2;
    } elsif ($month_string eq "APR"){
	$month_number=3;
    } elsif ($month_string eq "MAY"){
	$month_number=4;
    } elsif ($month_string eq "JUN"){
	$month_number=5;
    } elsif ($month_string eq "JUL"){
	$month_number=6;
    } elsif ($month_string eq "AUG"){
	$month_number=7;
    } elsif ($month_string eq "SEP"){
	$month_number=8;
    } elsif ($month_string eq "OCT"){
	$month_number=9;
    } elsif ($month_string eq "NOV"){
	$month_number=10;
    } elsif ($month_string eq "DEC"){
	$month_number=11;
    }
    return $month_number;
}
